use crate::{Context, Pass, Scene};

pub struct Renderer<'s> {
    ctx: Context<'s>,
    passes: Vec<Box<dyn Pass>>
}

impl<'s> Renderer<'s> {
    pub fn new(ctx: Context<'s>) -> Self {
        Self { ctx, passes: vec![] }
    }

    pub fn add_pass<P: 'static + Pass>(&mut self, mut pass: P) {
        pass.init(&self.ctx);
        self.passes.push(Box::new(pass))
    }

    pub fn resize(&mut self, width: u32, height: u32) {
        self.ctx.resize(width, height)
    }

    pub fn render(&mut self, scene: &mut Scene) {
        scene.prepare(&self.ctx);

        let surf_tex = self.ctx.surface.get_current_texture().unwrap();
        let view = surf_tex.texture.create_view(&wgpu::TextureViewDescriptor {
            label: None,
            format: Some(self.ctx.config.format),
            dimension: Some(wgpu::TextureViewDimension::D2),
            ..Default::default()
        });

        let mut encoder = self.ctx.create_command_encoder();
        
        for pass in self.passes.iter_mut() {
            pass.draw(&self.ctx, &view, &mut encoder, scene)
        }

        self.ctx.queue.submit([encoder.finish()]);
        surf_tex.present();
    }
}

// TODO: DeferedRenderer

// TODO: ForwardPlusRenderer
